package object;
import java.util.Hashtable;

/**
 * This is the class of SymbolTable in compiler
 * To produce a instance of the SymbolTable you need to give it a SpellingTable first
 * @author YaoXiao
 * @version 0.0
 * @date 17/09/2013
 */
public class SymbolTable {
	Hashtable<String ,Token > hashtable = new Hashtable<String ,Token >();				//use hashtable to record 
 	long index = 0;		//represent the given index of a IDENTIFIER which is not in Symbol Table
	SpellingTable spellingTable;		//a pointer to SpellingTable. IDENTIFIERs will be added to it. We can get ID by index
	
	public SymbolTable(SpellingTable spellingTable) {
		initTable();
		this.spellingTable = spellingTable;
	}	
	/**
	 * add the initial elements which are the key words in C*13
	 */
	private void initTable(){
		//first, add all the keywords to the hashtable
		hashtable.put("and",  new Token("AND","" ));
		hashtable.put("bool",  new Token("BOOL","" ));
		hashtable.put("branch",  new Token("BRANCH","" ));
		hashtable.put("case",  new Token("CASE","" ));
		hashtable.put("continue",  new Token("CONTINUE","" ));
		hashtable.put("default",  new Token("CONTINUE","" ));
		hashtable.put("else",  new Token("ELSE","" ));
		hashtable.put("end",  new Token("END","" ));
		hashtable.put("exit",  new Token("EXIT","" ));
		hashtable.put("if",  new Token("IF","" ));
		hashtable.put("int",  new Token("INT","" ));
		hashtable.put("loop",  new Token("LOOP","" ));
		hashtable.put("mod",  new Token("MOD","" ));
		hashtable.put("or",  new Token("OR","" ));
		hashtable.put("ref",  new Token("REF","" ));
		hashtable.put("return",  new Token("RETURN","" ));
		hashtable.put("void",  new Token("VOID","" ));		
		//second,add Boolean to the hashtable
		hashtable.put("true", new Token("BLIT","1"));
		hashtable.put("false", new Token("BLIT","0"));
	}
	
	/**
	 * Specify the wordToken into specific type of Token, then return the corresponding Token.
	 * It will add to the hashtable if the wordToken is a ID, and still not in hashtable.
	 * @param wordToken which pattern is letter(letter_|digit|dollar sign)*
	 * @return the corresponding Token
	 */
	public Token getToken(String wordToken) throws Exception{
		boolean found = hashtable.containsKey(wordToken);			//found represent if hashtable can find string wordToken in its Keys.
		if( found ){
			return hashtable.get(wordToken);
		} else{
			Token id = new Token("ID", String.valueOf(index));
			spellingTable.put(wordToken);
			hashtable.put(wordToken, id);
			if(index==Long.MAX_VALUE){
				throw new Exception("The identifier in one file can not over the maxValue of Long Type.(This should be improved in next version)");
			}else{
				index++;	
			}
			return id;
		}
	}
}
